package eu.catengine.common.manager;

import java.util.ArrayList;

import eu.catengine.common.iface.IDisposable;
import eu.catengine.common.iface.IManager;
import eu.catengine.scene.Scene;

/**
 * Manager odpowiedzialny za przechowywanie danych scen.
 * 
 * @author mbienkowski
 */
public class SceneManager implements IDisposable, IManager<SceneManager, Scene>
{
    private static volatile SceneManager mInstance;
    private ArrayList<Scene> mSceneList;
    private Scene mActiveScene;

    private SceneManager()
    {
	mSceneList = new ArrayList<Scene>();
	mActiveScene = null;
    }

    /**
     * Zwraca instanację managera.
     */
    public static SceneManager getInstance()
    {
	if (mInstance == null)
	{
	    mInstance = new SceneManager();
	}
	return mInstance;
    }

    /**
     * Dodaje scenę podaną jako parametr do managera.
     * 
     * @return <code>Scene</code> dodawany obiekt.
     */
    public Scene addScene(Scene scene)
    {
	if (scene == null)
	{
	    return null;
	}

	mSceneList.add(scene);

	if (mActiveScene == null)
	{
	    mActiveScene = scene;
	}

	return scene;
    }

    /**
     * Ustawia wybraną scenę na aktywną o ile znajduje się ona w managerze.
     * 
     * @param key
     *            <code>String</code> Nazwa sceny.
     */
    public void setActiveScene(String key)
    {
	for (int i = 0; i < mSceneList.size(); i++)
	{
	    if (mSceneList.get(i).getSceneName() == key)
	    {
		mActiveScene.setSceneIsRunning(false);
		mActiveScene.onChangeToInactiveScene();
		mActiveScene = mSceneList.get(i);
		mActiveScene.setSceneIsRunning(true);
		mActiveScene.onChangeToActiveScene();
		return;
	    }
	}
    }

    /**
     * Ustawia wybraną scenę na aktywną o ile znajduje się ona w managerze.
     * 
     * @param scene
     *            <code>Scene</code> Obiekt sceny.
     */
    public void setActiveScene(Scene scene)
    {
	if (mSceneList.contains(scene))
	{
	    setActiveScene(scene);
	}
    }

    /**
     * Zwraca aktywną scenę.
     * 
     * @return <code>Scene</code> aktualnie widziana scena przez użytkownika.
     */
    public Scene getActiveScene()
    {
	return mActiveScene;
    }

    @Override
    public Scene get(String name)
    {
	for (int i = 0; i < mSceneList.size(); i++)
	{
	    if (mSceneList.get(i).getSceneName() == name)
		return mSceneList.get(i);
	}

	return null;
    }

    @Override
    public void remove(String name)
    {
	Scene scene = get(name);

	if (scene != null)
	{
	    scene.dispose();
	    mSceneList.remove(scene);
	}
    }

    @Override
    public void remove(Scene object)
    {
	object.dispose();
	mSceneList.remove(object);
    }

    @Override
    public void dispose()
    {
	for (int i = 0; i < mSceneList.size(); i++)
	{
	    mSceneList.get(i).dispose();
	}

	mSceneList.clear();

	mInstance = null;
    }

}
